package com.stm.bi.report;

import com.stm.bi.core.util.DateUtils;
import com.stm.bi.model.Chart;
import com.stm.framework.core.util.StringUtil;
import com.stm.bi.constant.PaisiConstants;
import com.stm.bi.dto.query.PolicyEvolveDetailChartQuery;
import com.stm.bi.enums.PolicyEvolveType;
import com.stm.bi.enums.ProductTechnologyType;
import com.stm.ucenter.dto.vo.TreeVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @author liuyx
 * @date 2025/2/14 9:09
 */
@Component
public class PolicyEvolveDetailChartQueryExe extends AbsChartQueryExe<PolicyEvolveDetailChartQuery, Chart<List<List<Object>>>> {

    @Resource
    private PolicyEvolveDatatableQueryExe policyEvolveDatatableQueryExe;
    @Resource
    private PolicyEvolveTotalChartQueryExe policyEvolveTotalChartQueryExe;


    @Override
    public Chart query(Long orgId, String orgNo, PolicyEvolveDetailChartQuery query) {

        List<String> dates = DateUtils.getReportDateList(query.getStartDate(), query.getEndDate(), query.getDateType().getValue());

        // 获取左侧栏项目
        List<TreeVO> treeList = policyEvolveDatatableQueryExe.getRowInfoTrees(query.getPolicyId(), query.getType(), Boolean.FALSE);
        if (StringUtil.isEmpty(treeList)) {
            return new Chart();
        }

        // id列表
        List<Long> idList = treeList.stream().map(TreeVO::getId).toList();
        List<Map> maps;
        if (StringUtil.isEmpty(idList)) {
            maps = new ArrayList<>();
        } else {
            maps = policyEvolveTotalChartQueryExe.getOriginalData(orgNo, query.getType(), query.getDateType().getValue(), dates, idList);
        }

        return setChartData(maps, query, treeList, dates);
    }


    public Chart<List<List<Object>>> setChartData(List<Map> maps, PolicyEvolveDetailChartQuery query, List<TreeVO> treeList, List<String> dateList) {

        String column;
        // 销量
        if (query.getDataType().equals(PaisiConstants.SALES_AMOUNT)) {
            column = PaisiConstants.SALES_COLUMN;
        } else {
            // 客数
            column = PaisiConstants.CUSTOMER_NUM_COLUMN;
        }


        // 整年合计
        Map<Long, BigDecimal> totalMap = new HashMap<>();
        Map<String, Map<Long, BigDecimal>> totalDateMap = new HashMap<>();

        // 计算合计
        for (Map map : maps) {
            Long id = (Long) map.get("policy_id");
            String date = map.get("date").toString();
            String productTechnology = map.get("product_technology") != null ? map.get("product_technology").toString() : "";
            BigDecimal value = new BigDecimal(map.get(column).toString());
            if (productTechnology.equals(ProductTechnologyType.EXPAND.getValue())
                    || productTechnology.equals(ProductTechnologyType.EXTEND.getValue())) {
                id = id + PolicyEvolveDatatableQueryExe.ADD_ID_NUM;
            }
            totalMap.put(id, totalMap.getOrDefault(id, BigDecimal.ZERO).add(value));

            if (!totalDateMap.containsKey(date)) {
                totalDateMap.put(date, new HashMap<>());
            }
            totalDateMap.get(date).put(id, value);
        }

        // 按照values值进行大小排序
        List<Map.Entry<Long, BigDecimal>> sortedList;
        if (query.getLimit() > 0) {
            sortedList = totalMap.entrySet()
                    .stream()
                    .sorted(Map.Entry.<Long, BigDecimal>comparingByValue().reversed())
                    .limit(query.getLimit())
                    .toList();
        } else {
            sortedList = totalMap.entrySet()
                    .stream()
                    .sorted(Map.Entry.comparingByValue())
                    .limit(Math.abs(query.getLimit()))
                    .toList();
        }

        String lastDate = totalDateMap.keySet().stream()
                .max(String::compareTo)
                .orElse(null);

        // 表格数据
        List<List<Object>> data = new ArrayList<>();
        for (String date : dateList) {
            List<Object> row = new ArrayList<>();
            row.add(DateUtils.getReportDateName(date, query.getDateType().getValue()));
            // 按日期添加数据
            Map<Long, BigDecimal> rowMap = totalDateMap.get(date);
            if (rowMap != null) {
                for (Map.Entry<Long, BigDecimal> entry : sortedList) {
                    Long id = entry.getKey();
                    BigDecimal value = rowMap.get(id);
                    if (value != null) {
                        // 添加值到行数据中（根据查询类型转换单位）
                        if (query.getDataType().equals(PaisiConstants.SALES_AMOUNT)) {
                            // 销售额转为万元
                            row.add(value.divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP));
                        } else {
                            // 客户数保持整数
                            row.add(value.setScale(0, RoundingMode.HALF_UP));
                        }
                    } else {
                        row.add(BigDecimal.ZERO);
                    }
                }
                // 最后月份前空值补零
            } else if (lastDate!= null && date.compareTo(lastDate) <= 0) {
                sortedList.forEach(code -> row.add(BigDecimal.ZERO));
            }
            data.add(row);
        }

        Map<Long, TreeVO> idNameMap = treeList.stream().collect(Collectors.toMap(TreeVO::getId, Function.identity()));

        Chart<List<List<Object>>> chart = new Chart<>();
        List<String> items = chart.getItems();
        List<List<Object>> extend = new ArrayList<>();
        // 数据项

        for (Map.Entry<Long, BigDecimal> entry : sortedList) {
            Long id = entry.getKey();
            TreeVO tree = idNameMap.get(id);
            String name;
            if (PolicyEvolveType.PRODUCT_FEATURE.getValue().equals(query.getType())) {
                ProductTechnologyType productTechnologyType = ProductTechnologyType.getProductTechnologyType(tree.getType());
                name = productTechnologyType != null ? tree.getLabel() + "-" + productTechnologyType.getDesc() : tree.getLabel();
            } else {
                name = tree.getLabel();
            }
            items.add(name);
            List<Object> row = new ArrayList<>();
            row.add(name);
            // 添加值到行数据中（根据查询类型转换单位）
            if (query.getDataType().equals(PaisiConstants.SALES_AMOUNT)) {
                // 销售额转为万元
                row.add(entry.getValue().divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP));
            } else {
                // 客户数保持整数
                row.add(entry.getValue().setScale(0, RoundingMode.HALF_UP));
            }
            row.add(null);
            row.add(0);
            extend.add(row);
        }

        chart.setDatas(data);
        chart.setExtend(extend);
        return chart;
    }


    @Override
    public String getReportName() {
        return "方针占比推移详情表";
    }
}
